package com.yaorange.jk.shiro;

import com.yaorange.jk.entity.Module;
import com.yaorange.jk.entity.Role;
import com.yaorange.jk.entity.User;
import com.yaorange.jk.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author coach tam
 * @date 2017/11/3
 */
public class AuthRealm extends AuthorizingRealm {
    private UserService userService;
    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("开始授权...");
        SimpleAuthorizationInfo result = new SimpleAuthorizationInfo();
        //用来封装该用户所有的权限
        List<String> permissionList = new ArrayList<>();
        //获取当前用户
        User user = (User) principalCollection.fromRealm(this.getName()).iterator().next();

        //填充permissionList
        Set<Role> roleSet = user.getRoleSet();
        for (Role role:roleSet) {
            Set<Module> moduleSet = role.getModuleSet();
            for (Module module: moduleSet) {
               permissionList.add(module.getCpermission());
            }
        }
        //将permissionList加入shiro
        result.addStringPermissions(permissionList);
        return result;
    }


    /**
     * 认证/登录
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("开始认证...");
        //向下转型 （AuthenticationToken 父 ,UsernamePasswordToken 子  ）
        UsernamePasswordToken token = (UsernamePasswordToken)authenticationToken;
        //查询数据库的用户名，密码
        User user = userService.findByUsername(token.getUsername());
        //避免no session，马上加载dept对象
        user.getDept().getDeptName();
        Set<Role> roleSet = user.getRoleSet();
        for (Role role:roleSet) {
            Set<Module> moduleSet = role.getModuleSet();
            for (Module module: moduleSet) {
                module.getCpermission();
            }
        }

        //将user转成shiro可以识别的authenticationInfo对象
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
        return info;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}
